
package com.gcloud.mesh.dcs.dao;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.gcloud.framework.db.PageResult;
import com.gcloud.framework.db.dao.impl.JdbcBaseDaoImpl;
import com.gcloud.mesh.dcs.entity.AppInstanceEntity;
import com.gcloud.mesh.dcs.enums.SchedulerJobStatus;
import com.gcloud.mesh.dcs.service.AuthorityService;
import com.gcloud.mesh.header.enums.AuthorityResourceClassification;
import com.gcloud.mesh.header.msg.dcs.ListByClassificationMsg;
import com.gcloud.mesh.header.msg.dcs.PageInstanceMsg;
import com.gcloud.mesh.header.vo.dcs.AppDetailItemVo;
import com.gcloud.mesh.header.vo.dcs.AppInstanceVo;
import com.gcloud.mesh.header.vo.dcs.AuthorityVo;
import com.gcloud.mesh.header.vo.dcs.VmItemVo;

@Repository
public class AppInstanceDao extends JdbcBaseDaoImpl<AppInstanceEntity, String> {

	@Autowired
	private AuthorityService authorityService;

	public void deleteByAppId(String appId) {
		StringBuffer buff = new StringBuffer();
		buff.append(" delete from dcs_app_instance where app_id =  ");
		String appIdStr = "'" + appId + "'";
		buff.append(appIdStr);
		jdbcTemplate.execute(buff.toString());

	}

	public List<AppInstanceEntity> findByCloudResourceId(String cloudResourceId){
		StringBuffer buff = new StringBuffer();
		buff.append(" select i.* from dcs_app_instance i left join dcs_apps da on i.app_id = da.id ");
		buff.append(" where da.cloud_resource_id = ? ");
		List<Object> values = new ArrayList<>();
		values.add(cloudResourceId);
		return findBySql(buff.toString(), values);
	}
	public void deleteByInstanceId(String instanceId) {
		StringBuffer buff = new StringBuffer();
		buff.append(" delete from dcs_app_instance where instance_id = ");
		String instanceIdStr = "'" + instanceId + "'";
		buff.append(instanceIdStr);
		jdbcTemplate.execute(buff.toString());
	}

	public int count() {
		StringBuilder sql = new StringBuilder("SELECT COUNT(*) FROM dcs_app_instance WHERE 1=1");
		return this.countBySql(sql.toString(), new ArrayList<Object>());
	}

	public int countByDatacenter(String datacenterId) {
		StringBuilder sql = new StringBuilder("SELECT COUNT(*) FROM dcs_app_instance i ");
		sql.append("left join dcs_apps da on i.app_id = da.id "
				+ "left join asset_cloud_resources acr on da.cloud_resource_id = acr.id where acr.datacenter_id = ");
		sql.append("'" + datacenterId + "'");
		return this.countBySql(sql.toString(), new ArrayList<Object>());
	}

	public void updateAppIdBySrcId(String srcInstanceId, String destInstanceId) {
		super.jdbcTemplate.update("update dcs_app_instance set instance_id = ? where instance_id = ?", destInstanceId,
				srcInstanceId);
	}

	public List<AppInstanceVo> listInstancesByAppId(String appId) {
		StringBuffer buff = new StringBuffer();
		List<Object> values = new ArrayList<>();
		buff.append(
				" select ai.*,ai.name as instanceName,sj.status, acr.id as srcCloudResourceId, sj.dst_cloud_resource_id as dstCloudResourceId,sj.dst_datacenter_id as dstDatacenterId, ad.id as srcDatacenterId from dcs_app_instance ai ");
		buff.append(
				" left join dcs_scheduler_jobs sj on ai.instance_id = sj.instance_id left join dcs_apps da on da.id = ai.app_id ");
		buff.append(" left join asset_cloud_resources acr on da.cloud_resource_id = acr.id  ");
		buff.append(" left join asset_datacenters ad on acr.datacenter_id = ad.id where 1 = 1 ");
		if (StringUtils.isNotBlank(appId)) {
			buff.append(" and ai.app_id = ? ");
			values.add(appId);
		}
		List<AppInstanceVo> instances = findBySql(buff.toString(), values, AppInstanceVo.class);
		return instances;
	}

	public PageResult<VmItemVo> vmpage(String name, Integer type, String cloudResourceId, Integer pageNo,
			Integer pageSize, String datacenterId, Class<VmItemVo> class1) {
		List<Object> values = new ArrayList<>();

		StringBuilder sb = new StringBuilder();
		sb.append(
				"SELECT a.*, c.name AS cloudResourceName, c.type as resourceType, c.datacenter_id AS datacenter_id, dai.name as instanceName,dai.instance_id  FROM dcs_apps a LEFT JOIN asset_cloud_resources c ON a.cloud_resource_id = c.id ");
		sb.append(" left join dcs_app_instance dai on dai.app_id = a.id ");
		sb.append(" where 1=1 ");

		sb.append(" AND ( c.type = 2 or c.type = 3) ");

		if (StringUtils.isNotBlank(name)) {
			sb.append(" AND a.name LIKE concat('%', ?, '%')");
			values.add(name);
		}

		if (StringUtils.isNotBlank(cloudResourceId)) {
			sb.append(" AND a.cloud_resource_id = ?");
			values.add(cloudResourceId);
		}
		if (StringUtils.isNotBlank(datacenterId)) {
			sb.append(" AND c.datacenter_id = ?");
			values.add(datacenterId);
		}

		sb.append(" AND (deleted = 0 or deleted is null) ");

		checkResourceAuthority(sb);

		sb.append(" ORDER BY a.create_time desc ");
		return this.findBySql(sb.toString(), values, pageNo, pageSize, VmItemVo.class);
	}

	private StringBuilder checkResourceAuthority(StringBuilder sql) {

		ListByClassificationMsg msg = new ListByClassificationMsg();
		msg.setClassification(AuthorityResourceClassification.APP.getName());
		List<AuthorityVo> authorities = null;
		try {
			authorities = authorityService.listByClassification(msg);
		} catch (Exception e) {

		}
		if (authorities != null) {
			for (AuthorityVo vo : authorities) {
				if (!vo.getEnabled()) {
					sql.append(" and a.from != 'sync' ");
					break;
				}
			}
		}

		return sql;
	}

	public PageResult<AppInstanceVo> instancePage(PageInstanceMsg msg) {
		StringBuffer buff = new StringBuffer();
		List<Object> values = new ArrayList<>();
		buff.append(
				" select da.name as appName,acr.type, ai.*,ai.name as instanceName,sj.status, acr.id as srcCloudResourceId, sj.dst_cloud_resource_id as dstCloudResourceId,sj.dst_datacenter_id as dstDatacenterId, ad.id as srcDatacenterId from dcs_app_instance ai ");
		buff.append(
				" left join dcs_scheduler_jobs sj on ai.instance_id = sj.instance_id left join dcs_apps da on da.id = ai.app_id ");
		buff.append(" left join asset_cloud_resources acr on da.cloud_resource_id = acr.id  ");
		buff.append(" left join asset_datacenters ad on acr.datacenter_id = ad.id where 1 = 1 ");
		if (StringUtils.isNotBlank(msg.getInstanceId())) {
			buff.append(" and ai.instance_id = ? ");
			values.add(msg.getInstanceId());
		}
		buff.append(" and (sj.status is null or sj.status != ? )");
		buff.append(" order by ad.id");
		values.add(SchedulerJobStatus.FAIL.getValue());
		PageResult<AppInstanceVo> instances = findBySql(buff.toString(), values, msg.getPageNo(), msg.getPageSize(),
				AppInstanceVo.class);
		return instances;
	}

}
